﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms; // 需要引用 System.Windows.Forms
using System.Drawing;      // 需要引用 System.Drawing
using Autodesk.Revit.DB;
using Autodesk.Revit.DB.Analysis;   // HVACLoadSpaceType 在这里
using Autodesk.Revit.DB.Mechanical; // Space 在这里
using Autodesk.Revit.UI;
using Autodesk.Revit.UI.Selection; // 需要引用 RevitAPIUI
using Autodesk.Revit.Attributes;

// --- 使用别名避免冲突 ---
using WinForms = System.Windows.Forms;
using Drawing = System.Drawing;

namespace RevitApiExample // 请确保与您项目的命名空间一致
{
    //====================================================================
    // 主命令类: BatchChangeSpaceTypeCommand
    //====================================================================
    [Transaction(TransactionMode.Manual)]
    [Regeneration(RegenerationOption.Manual)]
    public class BatchChangeSpaceTypeCommand : IExternalCommand
    {
        public Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements)
        {
            UIApplication uiapp = commandData.Application;
            UIDocument uidoc = uiapp.ActiveUIDocument;
            Document doc = uidoc.Document;
            Selection sel = uidoc.Selection;

            // --- 1. 用户选择多个 Space 元素 ---
            IList<Reference> selectedRefs = null;
            try
            {
                // 使用过滤器确保只选择 Space
                ISelectionFilter spaceFilter = new SpaceSelectionFilter();
                selectedRefs = sel.PickObjects(ObjectType.Element, spaceFilter, "请选择一个或多个要修改类型的空间 (Select one or more Spaces)");

                if (selectedRefs == null || selectedRefs.Count == 0)
                {
                    return Result.Cancelled; // 用户未选择任何内容
                }
            }
            catch (Autodesk.Revit.Exceptions.OperationCanceledException)
            {
                return Result.Cancelled; // 用户按 ESC 取消选择
            }
            catch (Exception ex)
            {
                message = $"选择空间时出错: {ex.Message}";
                TaskDialog.Show("选择错误", message);
                return Result.Failed;
            }

            // --- 2. 获取所有可用的空间类型 ---
            var availableSpaceTypes = new FilteredElementCollector(doc)
                .OfClass(typeof(HVACLoadSpaceType))
                .Cast<HVACLoadSpaceType>()
                .OrderBy(st => st.Name)
                .ToList();

            if (!availableSpaceTypes.Any())
            {
                message = "项目中未定义任何空间类型 (HVACLoadSpaceType)。无法进行修改。";
                TaskDialog.Show("错误", message);
                return Result.Failed;
            }

            // --- 3. 用户选择目标空间类型 ---
            ElementId targetSpaceTypeId = ElementId.InvalidElementId;
            // 注意：这里我们直接在此文件中定义 SelectSpaceTypeForm 类 (或者您可以将其提取到单独文件)
            using (SelectSpaceTypeForm form = new SelectSpaceTypeForm(availableSpaceTypes))
            {
                if (form.ShowDialog() == WinForms.DialogResult.OK)
                {
                    targetSpaceTypeId = form.SelectedSpaceTypeId;
                }
                else
                {
                    return Result.Cancelled; // 用户在选择类型时取消
                }
            }

            if (targetSpaceTypeId == null || targetSpaceTypeId == ElementId.InvalidElementId)
            {
                message = "未能获取有效的空间类型选择。";
                TaskDialog.Show("错误", message);
                return Result.Failed;
            }

            // --- 4. 执行批量修改 ---
            int successCount = 0;
            int failCount = 0;
            using (Transaction tx = new Transaction(doc, "批量修改空间类型"))
            {
                tx.Start();
                try
                {
                    foreach (Reference refElem in selectedRefs)
                    {
                        Element elem = doc.GetElement(refElem);
                        if (elem is Space space) // 确认是 Space 类型
                        {
                            try
                            {
                                // 如果类型未改变，也算成功（或跳过）
                                if (space.SpaceTypeId != targetSpaceTypeId)
                                {
                                    space.SpaceTypeId = targetSpaceTypeId;
                                }
                                successCount++;
                            }
                            catch (Exception ex)
                            {
                                // 记录单个空间修改失败的情况
                                failCount++;
                                System.Diagnostics.Debug.WriteLine($"修改空间 ID {space.Id} 类型时出错: {ex.Message}");
                                // 可以选择继续处理下一个，或者直接回滚报错
                            }
                        }
                        else
                        {
                            // 理论上过滤器会阻止这种情况，但以防万一
                            failCount++;
                            System.Diagnostics.Debug.WriteLine($"选中的元素 ID {elem.Id} 不是 Space 类型。");
                        }
                    }

                    // 根据是否有失败决定是否提交
                    if (failCount > 0 && successCount == 0) // 如果全部失败
                    {
                        tx.RollBack();
                        message = $"未能成功修改任何空间的类型 ({failCount} 个失败)。";
                        TaskDialog.Show("批量修改失败", message);
                        return Result.Failed;
                    }
                    else // 只要有成功的就提交
                    {
                        tx.Commit();
                    }
                }
                catch (Exception ex)
                {
                    tx.RollBack();
                    message = $"执行批量修改时发生严重错误: {ex.Message}";
                    TaskDialog.Show("错误", message);
                    return Result.Failed;
                }
            }

            // --- 5. 显示结果 ---
            string resultMsg = $"成功修改了 {successCount} 个空间的类型。";
            if (failCount > 0)
            {
                resultMsg += $"\n有 {failCount} 个元素未能成功修改（详情请查看调试输出）。";
            }
            TaskDialog.Show("批量修改完成", resultMsg);

            return Result.Succeeded;
        }
    }

    //====================================================================
    // 辅助选择过滤器类: SpaceSelectionFilter
    // (如果项目中其他地方已定义，可以移除此定义并确保可访问)
    //====================================================================
    public class SpaceSelectionFilter : ISelectionFilter
    {
        public bool AllowElement(Element elem)
        {
            // 只允许选择 Space 元素
            return elem is Space;
        }

        public bool AllowReference(Reference reference, XYZ position)
        {
            // 我们按元素选择，通常返回 true 或 false 都可以，这里按元素逻辑返回 false
            return false;
        }
    }

    //====================================================================
    // 辅助窗体类: SelectSpaceTypeForm
    // (从 ChangeSpaceTypeCommand.cs 复制过来，或者提取到单独文件)
    //====================================================================
    public class SelectSpaceTypeForm : WinForms.Form
    {
        // --- 控件字段 ---
        private WinForms.ComboBox comboBoxSpaceTypes;
        private WinForms.Button buttonOk;
        private WinForms.Button buttonCancel;
        private WinForms.Label labelInstruction;
        private Dictionary<string, ElementId> _spaceTypeMap;

        // --- 公开属性 ---
        public ElementId SelectedSpaceTypeId { get; private set; } = ElementId.InvalidElementId;

        // --- 构造函数 ---
        public SelectSpaceTypeForm(IList<HVACLoadSpaceType> spaceTypes)
        {
            InitializeComponent(); // 初始化控件
            _spaceTypeMap = new Dictionary<string, ElementId>();

            // 填充下拉列表
            foreach (var type in spaceTypes)
            {
                if (type != null && !string.IsNullOrEmpty(type.Name))
                {
                    string displayName = $"{type.Name} (ID: {type.Id.IntegerValue})";
                    if (!_spaceTypeMap.ContainsKey(displayName))
                    {
                        comboBoxSpaceTypes.Items.Add(displayName);
                        _spaceTypeMap.Add(displayName, type.Id);
                    }
                }
            }

            // 设置默认选项
            if (comboBoxSpaceTypes.Items.Count > 0)
            {
                comboBoxSpaceTypes.SelectedIndex = 0;
            }
            else
            {
                buttonOk.Enabled = false; // 没有可选项则禁用确定按钮
            }
        }

        // --- 初始化控件布局 ---
        private void InitializeComponent()
        {
            this.comboBoxSpaceTypes = new WinForms.ComboBox();
            this.buttonOk = new WinForms.Button();
            this.buttonCancel = new WinForms.Button();
            this.labelInstruction = new WinForms.Label();
            this.SuspendLayout();

            // labelInstruction
            this.labelInstruction.AutoSize = true;
            this.labelInstruction.Location = new Drawing.Point(12, 15);
            this.labelInstruction.Name = "labelInstruction";
            this.labelInstruction.Size = new Drawing.Size(149, 13); // 根据中文调整
            this.labelInstruction.Text = "请选择目标空间类型:";

            // comboBoxSpaceTypes
            this.comboBoxSpaceTypes.Anchor = ((WinForms.AnchorStyles)(((WinForms.AnchorStyles.Top | WinForms.AnchorStyles.Left)
            | WinForms.AnchorStyles.Right)));
            this.comboBoxSpaceTypes.DropDownStyle = WinForms.ComboBoxStyle.DropDownList; // 设置为下拉列表样式
            this.comboBoxSpaceTypes.FormattingEnabled = true;
            this.comboBoxSpaceTypes.Location = new Drawing.Point(15, 35);
            this.comboBoxSpaceTypes.Name = "comboBoxSpaceTypes";
            this.comboBoxSpaceTypes.Size = new Drawing.Size(257, 21); // 调整大小

            // buttonOk
            this.buttonOk.Anchor = ((WinForms.AnchorStyles)((WinForms.AnchorStyles.Bottom | WinForms.AnchorStyles.Right)));
            this.buttonOk.DialogResult = WinForms.DialogResult.OK; // 设置 DialogResult
            this.buttonOk.Location = new Drawing.Point(116, 70); // 调整位置
            this.buttonOk.Name = "buttonOk";
            this.buttonOk.Size = new Drawing.Size(75, 23);
            this.buttonOk.Text = "确定";
            this.buttonOk.UseVisualStyleBackColor = true;
            this.buttonOk.Click += new System.EventHandler(this.ButtonOk_Click); // 绑定点击事件

            // buttonCancel
            this.buttonCancel.Anchor = ((WinForms.AnchorStyles)((WinForms.AnchorStyles.Bottom | WinForms.AnchorStyles.Right)));
            this.buttonCancel.DialogResult = WinForms.DialogResult.Cancel; // 设置 DialogResult
            this.buttonCancel.Location = new Drawing.Point(197, 70); // 调整位置
            this.buttonCancel.Name = "buttonCancel";
            this.buttonCancel.Size = new Drawing.Size(75, 23);
            this.buttonCancel.Text = "取消";
            this.buttonCancel.UseVisualStyleBackColor = true;

            // SelectSpaceTypeForm (窗体本身)
            this.AcceptButton = this.buttonOk; // 按 Enter 触发确定按钮
            this.CancelButton = this.buttonCancel; // 按 Esc 触发取消按钮
            this.ClientSize = new Drawing.Size(284, 111); // 调整窗体大小
            this.Controls.Add(this.labelInstruction);
            this.Controls.Add(this.comboBoxSpaceTypes);
            this.Controls.Add(this.buttonOk);
            this.Controls.Add(this.buttonCancel);
            this.FormBorderStyle = WinForms.FormBorderStyle.FixedDialog; // 固定边框
            this.MaximizeBox = false; // 禁用最大化
            this.MinimizeBox = false; // 禁用最小化
            this.Name = "SelectSpaceTypeForm";
            this.ShowIcon = false; // 不显示图标
            this.ShowInTaskbar = false; // 不在任务栏显示
            this.StartPosition = WinForms.FormStartPosition.CenterParent; // 居中于父窗口
            this.Text = "选择空间类型"; // 设置标题
            this.ResumeLayout(false);
            this.PerformLayout();
        }

        // --- 确定按钮点击事件处理 ---
        private void ButtonOk_Click(object sender, EventArgs e)
        {
            if (comboBoxSpaceTypes.SelectedItem != null)
            {
                string selectedDisplayName = comboBoxSpaceTypes.SelectedItem.ToString();
                if (_spaceTypeMap.TryGetValue(selectedDisplayName, out ElementId selectedId))
                {
                    this.SelectedSpaceTypeId = selectedId; // 设置选中的 ID
                    this.DialogResult = WinForms.DialogResult.OK; // 确认 DialogResult
                }
                else
                {
                    // 这种情况理论上不应发生
                    WinForms.MessageBox.Show("内部错误：无法找到所选类型对应的 ID。", "错误", WinForms.MessageBoxButtons.OK, WinForms.MessageBoxIcon.Error);
                    this.DialogResult = WinForms.DialogResult.None; // 阻止关闭
                }
            }
            else
            {
                WinForms.MessageBox.Show("请先选择一个空间类型。", "提示", WinForms.MessageBoxButtons.OK, WinForms.MessageBoxIcon.Warning);
                this.DialogResult = WinForms.DialogResult.None; // 阻止关闭
            }
        }
    }

} // end namespace